import socket

import threading
import time

serverAddr = ('0.0.0.0', 60000)

server = socket.socket()
clients = []
recvThreads = []

isSending = False

def main():
    global server
    server.bind(serverAddr)
    server.listen(100)
    print("Waiting for connect(listening 127.0.0.1:60000)")
    recvThread = threading.Thread(target = accept)
    recvThread.setDaemon(True)
    recvThread.start()
    print("Command line started, type help get usage")
    while True:

        print(">>> ",end = '')
        cmd = input('').lower().strip()
        if cmd == 'quit':
            print("Calling connected clients close...")
            for i in range(0, len(clients)):
                send(i, 'quit')
                time.sleep(0.5)
                clients[i].close()

                break
            break
        elif cmd == 'help':
            print('Usage:\n\tsendlines: send some text to a client\n\tquit:quit\n\thelp:show this message')
        elif cmd == 'sendlines':
            isSending = True
            try:
                if (len(clients)) == 0:
                    print("Error: No client connected!")
                    continue
                index = int(input(f"Index: (Correct number:1~{len(clients)}) ")) - 1
                se = ''
                print("Enter the message that you want to send, press Ctrl+C and Enter in a new line to Stop")
                while True:
                    try:
                        se += '\n' + input('send << ')
                    except (EOFError, KeyboardInterrupt):
                        print('')
                        break
                send(index, se)
            except:
                print('Error.')
                isSending = False
        elif cmd == '':
            pass
        else:
            print("Bad command!")


def recv(recv_from, addr):
    while True:
        recvData = recv_from.recv(102400).decode('utf-8')
        print(f"\nMessage from <{addr[0]}:{addr[1]}>: {recvData}")
        if (recvData.lower().strip() == 'quit'):
            print("Client calling quit. Closing connection now!")
            recv_from.close()
        if isSending:
            print("send << ", end = '')
        else:
            print(">>> ", end = '')
        time.sleep(0.3)

def send(index, text):
    clients[index].sendall(text.encode('utf-8'))
    isSending = False

def accept():
    # Accept and add client to clients pool
    while True:
        client, addr = server.accept()
        print(f"\nA new client <{addr[0]}:{addr[1]}> connected!")
        if isSending:
            print("send << ", end = '')
        else:
            print(">>> ", end = '')
        clients.append(client)
        th = threading.Thread(target = recv, args = (client,addr))
        th.setDaemon(True)
        th.start()

if __name__ == '__main__':
    main()
